﻿class CoordinateRotationGame extends MovieClip {
	var bounce:Number = -1;
	var stageWidth:Number;
	var stageHeight:Number;
	var ballCount:Number = 5;
	var balls:Array;
	var bounds:Array;
	var lines:Array;
	var mouseListener:Object;
	var isMouseDown:Boolean = false;
	var targetAreaBounds:Object;
	function CoordinateRotationGame() {
		init();
	}
	function init():Void {
		stageWidth = Stage.width;
		stageHeight = Stage.height;
		lines = new Array();
		createTargetArea();
		createBalls();
		createBounds();
		addMouseListener();
	}
	function createTargetArea():Void {
		var targetArea_mc:MovieClip = this.createEmptyMovieClip("targetArea_mc", this.getNextHighestDepth());
		targetArea_mc.lineStyle(1, 0x000000, 100);
		targetArea_mc.beginFill(0x0000ff, 60);
		targetArea_mc.lineTo(200, 0);
		targetArea_mc.lineTo(200, 200);
		targetArea_mc.lineTo(0, 200);
		targetArea_mc.lineTo(0, 0);
		targetArea_mc.endFill();
		targetArea_mc._x = stageWidth-targetArea_mc._width;
		targetArea_mc._y = stageHeight-targetArea_mc._height;
		targetAreaBounds = targetArea_mc.getBounds(this);
		targetArea_mc.onEnterFrame = mx.utils.Delegate.create(this, targetArea_onEnterFrame);
	}
	function targetArea_onEnterFrame():Void {
		var isAllInclude:Boolean = true;
		for (var i:Number = 0; i<balls.length; i++) {
			if (!(balls[i].x+balls[i].size/2<targetAreaBounds.xMax
				&& balls[i].x-balls[i].size/2>targetAreaBounds.xMin
				&& balls[i].y+balls[i].size/2<targetAreaBounds.yMax
				&& balls[i].y-balls[i].size/2>targetAreaBounds.yMin)) {
				isAllInclude = false;
			}
		}
		if (isAllInclude) {
			//球停止動
			for (var i:Number = 0; i<balls.length; i++) {
				balls[i].vx = 0;
				balls[i].vy = 0;
			}
			//停止所有動畫
			onEnterFrame = null;
			//不再監聽滑鼠事件
			Mouse.removeListener(mouseListener);
		}
	}
	function createBalls():Void {
		balls = new Array();
		for (var i:Number = 0; i<ballCount; i++) {
			var ball = new Ball(this.createEmptyMovieClip("ball"+i+"_mc", this.getNextHighestDepth()), 20);
			ball.x = stageWidth/2;
			ball.y = stageHeight/2;
			ball.vx = (Math.random()-Math.random())*10;
			ball.vy = (Math.random()-Math.random())*10;
			balls.push(ball);
		}
	}
	function createBounds():Void {
		bounds = new Array();
		bounds.push(new Line({x:0, y:stageHeight}, {x:stageWidth, y:stageHeight}));
		bounds.push(new Line({x:stageWidth, y:stageHeight}, {x:stageWidth, y:0}));
		bounds.push(new Line({x:stageWidth, y:0}, {x:0, y:0}));
		bounds.push(new Line({x:0, y:0}, {x:0, y:stageHeight}));
	}
	function addMouseListener():Void {
		mouseListener = {onMouseDown:mx.utils.Delegate.create(this, handleMouseDown), onMouseUp:mx.utils.Delegate.create(this, handleMouseUp)};
		Mouse.addListener(mouseListener);
	}
	function handleMouseDown():Void {
		if (!isMouseDown) {
			isMouseDown = true;
			this["mouse_down_x"] = this._xmouse;
			this["mouse_down_y"] = this._ymouse;
		}
	}
	function handleMouseUp():Void {
		isMouseDown = false;
		var xmouse:Number = this._xmouse;
		var ymouse:Number = this._ymouse;
		//建立線條MC
		var depth:Number = this.getNextHighestDepth();
		var line:MovieClip = this.createEmptyMovieClip("line"+depth, depth);
		line.lineStyle(0, 0x000000, 100);
		line.moveTo(this["mouse_down_x"], this["mouse_down_y"]);
		line.lineTo(xmouse, ymouse);
		//建立Line物件
		lines.push({mc:line, line:new Line({x:this["mouse_down_x"], y:this["mouse_down_y"]}, {x:xmouse, y:ymouse})});
		//刪除
		this["mouse_down_x"] = null;
		this["mouse_down_y"] = null;
		delete this["mouse_down_x"];
		delete this["mouse_down_y"];
	}
	function onEnterFrame():Void {
		for (var i:Number = 0; i<balls.length; i++) {
			var ball:Ball = balls[i];
			ball.x += ball.vx;
			ball.y += ball.vy;
			//檢測邊界
			for (var j:Number = 0; j<bounds.length; j++) {
				if (checkHit(ball, bounds[j], false)) {
					break;
				}
			}
			//檢測線條
			for (var j:Number = 0; j<lines.length; j++) {
				var ballBounds:Object = ball.getBounds();
				var lineBounds:Object = lines[j].line.getBounds();
				if (ballBounds.xMax>lineBounds.xMin && ballBounds.xMin<lineBounds.xMax && ballBounds.yMax>lineBounds.yMin && ballBounds.yMin<lineBounds.yMax) {
					if (checkHit(ball, lines[j].line, true)) {
						lines[j].mc.removeMovieClip();
						lines.splice(j, 1);
						break;
					}
				}
			}
		}
	}
	function checkHit(ball:Ball, line:Line, isDoubleSide:Boolean):Boolean {
		if (!isDoubleSide) {
			return checkHitOneSide(ball, line);
		} else {
			return checkHitOneSide(ball, line) || checkHitOneSide(ball, line.getReverseLine());
		}
	}
	function checkHitOneSide(ball:Ball, line:Line):Boolean {
		//求sin, cos
		var cos:Number = Math.cos(line.angle);
		var sin:Number = Math.sin(line.angle);
		//求球對線的相關位置
		var x1:Number = ball.x-line.x;
		var y1:Number = ball.y-line.y;
		//旋轉座標
		var y2:Number = cos*y1-sin*x1;
		//旋轉速率
		var vy1:Number = cos*ball.vy-sin*ball.vx;
		//用旋轉值執行彈開
		if (y2>-ball.size/2 && y2<vy1) {
			//旋轉座標
			var x2:Number = cos*x1+sin*y1;
			//旋轉速率
			var vx1:Number = cos*ball.vx+sin*ball.vy;
			y2 = -ball.size/2;
			vy1 *= bounce;
			//把所有一切都旋轉回去 
			x1 = cos*x2-sin*y2;
			y1 = cos*y2+sin*x2;
			ball.vx = cos*vx1-sin*vy1;
			ball.vy = cos*vy1+sin*vx1;
			ball.x = line.x+x1;
			ball.y = line.y+y1;
			return true;
		} else {
			return false;
		}
	}
}
